package com.kaolafm.kradio.k_navi_map.amap;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.navi.model.AMapNaviPath;
import com.amap.api.navi.model.RouteOverlayOptions;
import com.amap.api.navi.view.RouteOverLay;
import com.kaolafm.kradio.k_navi_map.R;
import com.kaolafm.kradio.k_navi_map.base.IMapViewManager;
import com.kaolafm.kradio.k_navi_map.common.Constants;
import com.kaolafm.kradio.k_navi_map.listener.OnMapViewTouchListener;
import com.kaolafm.kradio.k_navi_map.location.bean.MapLocationData;

/**
 * Created by kaolafm on 2018/4/15.
 */

public class AMapViewManager implements IMapViewManager {

    private Context mContext;

    private MapView mMapView;
    private AMap mAMap;
    private UiSettings mUiSettings;

    private Marker mLocationMark;
    private LatLng mCurLatLng;
    private float mCurBearing;

    private MyCancelCallback myCancelCallback = new MyCancelCallback();

    private boolean useMoveToLocationWithMapMode = true;

    @Override
    public void setView(View view, Bundle savedInstanceState, Context context) {
        mMapView = (MapView) view;
        mMapView.onCreate(savedInstanceState);
        mAMap = mMapView.getMap();
        mUiSettings = mAMap.getUiSettings();
        mUiSettings.setZoomControlsEnabled(false);
        mContext = context;
    }

    @Override
    public void onResume() {
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        mMapView.onPause();
    }

    @Override
    public void onSaveInstanceState(Bundle paramBundle) {
        mMapView.onSaveInstanceState(paramBundle);
    }

    @Override
    public void onDestory() {
        mMapView.onDestroy();
    }

    @Override
    public void zoomIn() {
        mAMap.animateCamera(CameraUpdateFactory.zoomIn(), Constants.MAP_ANIMATE_TIME, null);
    }

    @Override
    public void zoomOut() {
        mAMap.animateCamera(CameraUpdateFactory.zoomOut(), Constants.MAP_ANIMATE_TIME, null);
    }

    @Override
    public void setTrafficEnabled(boolean enabled) {
        mAMap.setTrafficEnabled(enabled);
    }

    @Override
    public void setOnMapViewTouchListener(OnMapViewTouchListener onMapViewTouchListener) {
        mAMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent motionEvent) {
                onMapViewTouchListener.onTouch(motionEvent);
            }
        });
    }

    @Override
    public void updateLocationMark(MapLocationData data) {
        mCurBearing = data.getBearing();
        mCurLatLng = new LatLng(data.getLatitude(), data.getLongitude());
        if(mLocationMark == null){
            addLocationMark(mCurLatLng);
            return;
        }
        if(useMoveToLocationWithMapMode){
            startMoveLocationAndMap(mCurLatLng);
            return;
        }
        startChangeLocation(mCurLatLng);
    }

    public void setUseMoveToLocationWithMapMode(boolean useMoveToLocationWithMapMode) {
        this.useMoveToLocationWithMapMode = useMoveToLocationWithMapMode;
    }

    @Override
    public void moveLocationAndMap() {
        startMoveLocationAndMap(mCurLatLng);
    }

    @Override
    public void setNaviMode(int mode) {
    }

    @Override
    public LatLng getCurLatLng() {
        return mCurLatLng;
    }

    @Override
    public void changeTilt(float tilt) {
        mAMap.moveCamera(CameraUpdateFactory.changeTilt(tilt));
    }

    public void drawRoute(AMapNaviPath path, LatLng starLatLng, LatLng endLatIng) {

        mLocationMark.remove();

        useMoveToLocationWithMapMode = false;

        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        builder.include(starLatLng);
        builder.include(endLatIng);
        LatLngBounds latlngBounds = builder.build();
        mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, Constants.MAP_PADDING));

        RouteOverLay routeOverLay = new RouteOverLay(mAMap, path, mContext);
        RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions();

        routeOverlayOptions.setArrowOnTrafficRoute(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture_aolr));
        routeOverlayOptions.setNormalRoute(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture));

        routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(mContext.getResources(),R.drawable.custtexture_no));
        routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture_green));
        routeOverlayOptions.setSlowTraffic(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture_slow));
        routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture_bad));
        routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custtexture_grayred));
        routeOverLay.setRouteOverlayOptions(routeOverlayOptions);
        routeOverLay.setTrafficLine(false);
        routeOverLay.addToMap();
    }

    private void addLocationMark(LatLng latLng) {
        mLocationMark = mAMap.addMarker(new MarkerOptions().position(latLng)
                .icon(BitmapDescriptorFactory.fromResource(android.R.drawable.ic_menu_view))
                .anchor(0.5f, 0.5f));
        mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
    }

    /**
     * 修改自定义定位小蓝点的位置
     * @param latLng
     */
    private void startChangeLocation(LatLng latLng) {
        if(mLocationMark != null) {
            LatLng curLatlng = mLocationMark.getPosition();
            if(curLatlng == null || !curLatlng.equals(latLng)) {
                mLocationMark.setPosition(latLng);
            }
        }
    }

    /**
     * 同时修改自定义定位小蓝点和地图的位置
     * @param latLng
     */
    private void startMoveLocationAndMap(LatLng latLng) {
        if(mLocationMark != null ) {
            LatLng markerLocation = mLocationMark.getPosition();
            Point screenPosition = mAMap.getProjection().toScreenLocation(markerLocation);
            mLocationMark.setPositionByPixels(screenPosition.x, screenPosition.y);

        }

        //移动地图，移动结束后，将小蓝点放到放到地图上
        myCancelCallback.setTargetLatlng(latLng);
        //动画移动的时间，最好不要比定位间隔长，如果定位间隔2000ms 动画移动时间最好小于2000ms，可以使用1000ms
        //如果超过了，需要在myCancelCallback中进行处理被打断的情况
        mAMap.animateCamera(CameraUpdateFactory.changeLatLng(latLng),200,myCancelCallback);

    }

    /**
     * 监控地图动画移动情况，如果结束或者被打断，都需要执行响应的操作
     */
    class MyCancelCallback implements AMap.CancelableCallback {

        LatLng targetLatlng;
        public void setTargetLatlng(LatLng latlng) {
            this.targetLatlng = latlng;
        }

        @Override
        public void onFinish() {
            if(mLocationMark != null && targetLatlng != null) {
                mLocationMark.setPosition(targetLatlng);
            }
        }

        @Override
        public void onCancel() {
            if(mLocationMark != null && targetLatlng != null) {
                mLocationMark.setPosition(targetLatlng);
            }
        }
    };
}
